#pragma once

#include "common.h"

/*! Constructs type name from a struct */
#define TXDNN_DECLARE_OBJECT(name) \
  struct name {};                  \
  typedef struct name* name##_t;


#if defined(__cplusplus)
extern "C" {
#endif

struct txdnnContext;
typedef struct txdnnContext* txdnnHandle_t;

// typedef void* txdaStream_t;
// typedef txdaStream_t txdnnAcceleratorQueue_t;

/*
 * TXDNN return codes
 */
typedef enum {
  TXDNN_STATUS_SUCCESS = 0,

  /* Uncategorized errors */
  TXDNN_STATUS_NOT_INITIALIZED = 1001,
  TXDNN_STATUS_SUBLIBRARY_VERSION_MISMATCH = 1002,
  TXDNN_STATUS_SERIALIZATION_VERSION_MISMATCH = 1003,
  TXDNN_STATUS_DEPRECATED = 1004,
  TXDNN_STATUS_LICENSE_ERROR = 1005,
  TXDNN_STATUS_RUNTIME_IN_PROGRESS = 1006,
  TXDNN_STATUS_RUNTIME_FP_OVERFLOW = 1007,
  TXDNN_STATUS_SUBLIBRARY_LOADING_FAILED = 1008,

  TXDNN_STATUS_BAD_PARAM = 2000,
  TXDNN_STATUS_BAD_PARAM_NULL_POINTER = 2002,
  TXDNN_STATUS_BAD_PARAM_MISALIGNED_POINTER = 2003,
  TXDNN_STATUS_BAD_PARAM_NOT_FINALIZED = 2004,
  TXDNN_STATUS_BAD_PARAM_OUT_OF_BOUND = 2005,
  TXDNN_STATUS_BAD_PARAM_SIZE_INSUFFICIENT = 2006,
  TXDNN_STATUS_BAD_PARAM_STREAM_MISMATCH = 2007,
  TXDNN_STATUS_BAD_PARAM_SHAPE_MISMATCH = 2008,
  TXDNN_STATUS_BAD_PARAM_DUPLICATED_ENTRIES = 2009,
  TXDNN_STATUS_BAD_PARAM_ATTRIBUTE_TYPE = 2010,

  TXDNN_STATUS_NOT_SUPPORTED = 3000,
  TXDNN_STATUS_NOT_SUPPORTED_GRAPH_PATTERN = 3001,
  TXDNN_STATUS_NOT_SUPPORTED_SHAPE = 3002,
  TXDNN_STATUS_NOT_SUPPORTED_DATA_TYPE = 3003,
  TXDNN_STATUS_NOT_SUPPORTED_LAYOUT = 3004,
  TXDNN_STATUS_NOT_SUPPORTED_INCOMPATIBLE_TXDA_DRIVER = 3005,
  TXDNN_STATUS_NOT_SUPPORTED_INCOMPATIBLE_TXDART = 3006,
  TXDNN_STATUS_NOT_SUPPORTED_ARCH_MISMATCH = 3007,
  TXDNN_STATUS_NOT_SUPPORTED_RUNTIME_PREREQUISITE_MISSING = 3008,
  TXDNN_STATUS_NOT_SUPPORTED_SUBLIBRARY_UNAVAILABLE = 3009,
  TXDNN_STATUS_NOT_SUPPORTED_SHARED_MEMORY_INSUFFICIENT = 3010,
  TXDNN_STATUS_NOT_SUPPORTED_PADDING = 3011,
  TXDNN_STATUS_NOT_SUPPORTED_BAD_LAUNCH_PARAM = 3012,

  TXDNN_STATUS_INTERNAL_ERROR = 4000,
  TXDNN_STATUS_INTERNAL_ERROR_COMPILATION_FAILED = 4001,
  TXDNN_STATUS_INTERNAL_ERROR_UNEXPECTED_VALUE = 4002,
  TXDNN_STATUS_INTERNAL_ERROR_HOST_ALLOCATION_FAILED = 4003,
  TXDNN_STATUS_INTERNAL_ERROR_DEVICE_ALLOCATION_FAILED = 4004,
  TXDNN_STATUS_INTERNAL_ERROR_BAD_LAUNCH_PARAM = 4005,
  TXDNN_STATUS_INTERNAL_ERROR_TEXTURE_CREATION_FAILED = 4006,

  TXDNN_STATUS_EXECUTION_FAILED = 5000,
  TXDNN_STATUS_EXECUTION_FAILED_TXDA_DRIVER = 5001,
  TXDNN_STATUS_EXECUTION_FAILED_TXBLAS = 5002,
  TXDNN_STATUS_EXECUTION_FAILED_TXDART = 5003,
  TXDNN_STATUS_EXECUTION_FAILED_TXRAND = 5004,

  TXDNN_STATUS_UNKNOWN = 2001 /* please transition to TXDNN_STATUS_BAD_PARAM instead */,
} txdnnStatus_t;

txdnnStatus_t TXDNNAPI txdnnCreate(txdnnHandle_t* handle);
txdnnStatus_t TXDNNAPI txdnnDestroy(txdnnHandle_t handle);
txdnnStatus_t TXDNNAPI txdnnSetStream(txdnnHandle_t handle /*txdaStream_t streamId*/);
txdnnStatus_t TXDNNAPI txdnnGetStream(txdnnHandle_t handle /*txdaStream_t *streamId*/);

/*
 * TXDNN data type
 */
typedef enum {
  TXDNN_DATA_FLOAT = 0,
  TXDNN_DATA_DOUBLE = 1,
  TXDNN_DATA_HALF = 2,
  TXDNN_DATA_INT8 = 3,
  TXDNN_DATA_INT32 = 4,
  TXDNN_DATA_UINT8 = 6,
  TXDNN_DATA_BFLOAT16 = 9,
  TXDNN_DATA_INT64 = 10,
  TXDNN_DATA_BOOLEAN = 11,
  TXDNN_DATA_FP8_E4M3 = 12,
  TXDNN_DATA_FP8_E5M2 = 13,
  TXDNN_DATA_FAST_FLOAT_FOR_FP8 = 14,
  TXDNN_DATA_NOT_SET = 15,
} txdnnDataType_t;

/*
 * TXDNN math type
 */
typedef enum {
    TXDNN_DEFAULT_MATH                    = 0,
    TXDNN_TENSOR_OP_MATH                  = 1,
    TXDNN_TENSOR_OP_MATH_ALLOW_CONVERSION = 2,
    TXDNN_FMA_MATH                        = 3,
} txdnnMathType_t;



/* Data structures to represent Tensors and the Neural Network Layer */
struct txdnnTensorStruct;
typedef struct txdnnTensorStruct* txdnnTensorDescriptor_t;


/*
 *  convolution mode
 */
typedef enum {
  TXDNN_CONVOLUTION = 0,
  TXDNN_CONV_TRANSPOSE = 1,
  TXDNN_GROUP_CONV = 2,
  TXDNN_DEPTHWISE_CONV = 3,
} txdnnConvolutionMode_t;

typedef void *txdnnBackendDescriptor_t;
// typedef struct txdnnBackendDescriptor* txdnnBackendDescriptor_t;


/* Sequence data descriptor */

typedef enum {
    TXDNN_SEQDATA_TIME_DIM  = 0, /* index in time */
    TXDNN_SEQDATA_BATCH_DIM = 1, /* index in batch */
    TXDNN_SEQDATA_BEAM_DIM  = 2, /* index in beam */
    TXDNN_SEQDATA_VECT_DIM  = 3  /* index in vector */
} txdnnSeqDataAxis_t;

struct txdnnSeqDataStruct;
typedef struct txdnnSeqDataStruct *txdnnSeqDataDescriptor_t;

#define TXDNN_SEQDATA_DIM_COUNT 4 /* dimension count */

txdnnStatus_t txdnnCreateSeqDataDescriptor(txdnnSeqDataDescriptor_t *seqDataDesc);

txdnnStatus_t txdnnDestroySeqDataDescriptor(txdnnSeqDataDescriptor_t seqDataDesc);

txdnnStatus_t txdnnSetSeqDataDescriptor(txdnnSeqDataDescriptor_t seqDataDesc,
                                        txdnnDataType_t dataType,
                                        int nbDims,
                                        const int dimA[],
                                        const txdnnSeqDataAxis_t axes[],
                                        size_t seqLengthArraySize,
                                        const int seqLengthArray[],
                                        void *paddingFill);

txdnnStatus_t txdnnGetSeqDataDescriptor(const txdnnSeqDataDescriptor_t seqDataDesc,
                                        txdnnDataType_t *dataType,
                                        int *nbDims,
                                        int nbDimsRequested,
                                        int dimA[],
                                        txdnnSeqDataAxis_t axes[],
                                        size_t *seqLengthArraySize,
                                        size_t seqLengthSizeRequested,
                                        int seqLengthArray[],
                                        void *paddingFill);

/* Multihead Attention */

/*
 * Multi-head attention options passed via 'attnMode' in txdnnSetAttnDescriptor().
 * Use the bitwise OR operator to combine several settings listed below.  Additional
 * minor options can be added here w/o changing or introducing new API functions.
 */
#define TXDNN_ATTN_QUERYMAP_ALL_TO_ONE 0         /* multiple Q-s map to a single (K,V) set when beam size > 1 */
#define TXDNN_ATTN_QUERYMAP_ONE_TO_ONE (1U << 0) /* multiple Q-s map to multiple (K,V) sets when beam size > 1 */
#define TXDNN_ATTN_DISABLE_PROJ_BIASES 0         /* no biases in attention input and output projections */
#define TXDNN_ATTN_ENABLE_PROJ_BIASES (1U << 1)  /* use biases in attention input and output projections */

typedef struct txdnnDropoutStruct* txdnnDropoutDescriptor_t;

struct txdnnAttnStruct;
typedef struct txdnnAttnStruct* txdnnAttnDescriptor_t;

txdnnStatus_t txdnnCreateAttnDescriptor(txdnnAttnDescriptor_t *attnDesc);

txdnnStatus_t txdnnDestroyAttnDescriptor(txdnnAttnDescriptor_t attnDesc);

txdnnStatus_t txdnnSetAttnDescriptor(txdnnAttnDescriptor_t attnDesc,
                                     unsigned attnMode,
                                     int nHeads,
                                     double scaler,
                                     txdnnDataType_t dataType,
                                     txdnnDataType_t computePrec,
                                     txdnnMathType_t mathType,
                                     txdnnDropoutDescriptor_t attnDropoutDesc,
                                     txdnnDropoutDescriptor_t postDropoutDesc,
                                     int qSize,
                                     int kSize,
                                     int vSize,
                                     int qProjSize,
                                     int kProjSize,
                                     int vProjSize,
                                     int oProjSize,
                                     int qoMaxSeqLength,
                                     int kvMaxSeqLength,
                                     int maxBatchSize,
                                     int maxBeamSize);

txdnnStatus_t txdnnGetAttnDescriptor(txdnnAttnDescriptor_t attnDesc,
                                     unsigned *attnMode,
                                     int *nHeads,
                                     double *scaler,
                                     txdnnDataType_t *dataType,
                                     txdnnDataType_t *computePrec,
                                     txdnnMathType_t *mathType,
                                     txdnnDropoutDescriptor_t *attnDropoutDesc,
                                     txdnnDropoutDescriptor_t *postDropoutDesc,
                                     int *qSize,
                                     int *kSize,
                                     int *vSize,
                                     int *qProjSize,
                                     int *kProjSize,
                                     int *vProjSize,
                                     int *oProjSize,
                                     int *qoMaxSeqLength,
                                     int *kvMaxSeqLength,
                                     int *maxBatchSize,
                                     int *maxBeamSize);

txdnnStatus_t txdnnGetMultiHeadAttnBuffers(txdnnHandle_t handle,
                                           const txdnnAttnDescriptor_t attnDesc,
                                           size_t *weightSizeInBytes,
                                           size_t *workSpaceSizeInBytes,
                                           size_t *reserveSpaceSizeInBytes);

typedef enum {
    TXDNN_MH_ATTN_Q_WEIGHTS = 0, /* input projection weights for 'queries' */
    TXDNN_MH_ATTN_K_WEIGHTS = 1, /* input projection weights for 'keys' */
    TXDNN_MH_ATTN_V_WEIGHTS = 2, /* input projection weights for 'values' */
    TXDNN_MH_ATTN_O_WEIGHTS = 3, /* output projection weights */
    TXDNN_MH_ATTN_Q_BIASES  = 4, /* input projection bias tensor for 'queries' */
    TXDNN_MH_ATTN_K_BIASES  = 5, /* input projection bias for 'keys' */
    TXDNN_MH_ATTN_V_BIASES  = 6, /* input projection bias for 'values' */
    TXDNN_MH_ATTN_O_BIASES  = 7, /* output projection biases */
} txdnnMultiHeadAttnWeightKind_t;

#define TXDNN_ATTN_WKIND_COUNT 8 /* Number of attention weight/bias tensors */

txdnnStatus_t txdnnGetMultiHeadAttnWeights(txdnnHandle_t handle,
                                           const txdnnAttnDescriptor_t attnDesc,
                                           txdnnMultiHeadAttnWeightKind_t wKind,
                                           size_t weightSizeInBytes,
                                           const void *weights,
                                           txdnnTensorDescriptor_t wDesc,
                                           void **wAddr);

txdnnStatus_t txdnnMultiHeadAttnForward(txdnnHandle_t handle,
                                        const txdnnAttnDescriptor_t attnDesc,
                                        int currIdx,
                                        const int loWinIdx[],
                                        const int hiWinIdx[],
                                        const int devSeqLengthsQO[],
                                        const int devSeqLengthsKV[],
                                        const txdnnSeqDataDescriptor_t qDesc,
                                        const void *queries,
                                        const void *residuals,
                                        const txdnnSeqDataDescriptor_t kDesc,
                                        const void *keys,
                                        const txdnnSeqDataDescriptor_t vDesc,
                                        const void *values,
                                        const txdnnSeqDataDescriptor_t oDesc,
                                        void *out,
                                        size_t weightSizeInBytes,
                                        const void *weights,
                                        size_t workSpaceSizeInBytes,
                                        void *workSpace,
                                        size_t reserveSpaceSizeInBytes,
                                        void *reserveSpace);


typedef struct txdnnDropoutStruct *txdnnDropoutDescriptor_t;

txdnnStatus_t txdnnCreateDropoutDescriptor(txdnnDropoutDescriptor_t *dropoutDesc);

txdnnStatus_t txdnnDestroyDropoutDescriptor(txdnnDropoutDescriptor_t dropoutDesc);

/*helper function to determine size of the states to be passed to txdnnSetDropoutDescriptor */
txdnnStatus_t txdnnDropoutGetStatesSize(txdnnHandle_t handle, size_t *sizeInBytes);

/*helper function to determine size of the reserve space to be passed to dropout forward/backward calls */
txdnnStatus_t txdnnDropoutGetReserveSpaceSize(txdnnTensorDescriptor_t xdesc, size_t *sizeInBytes);

txdnnStatus_t txdnnSetDropoutDescriptor(txdnnDropoutDescriptor_t dropoutDesc,
                          txdnnHandle_t handle,
                          float dropout,
                          void *states,
                          size_t stateSizeInBytes,
                          unsigned long long seed);

/* Restores the dropout descriptor to a previously saved-off state */
txdnnStatus_t txdnnRestoreDropoutDescriptor(txdnnDropoutDescriptor_t dropoutDesc,
                              txdnnHandle_t handle,
                              float dropout,
                              void *states,
                              size_t stateSizeInBytes,
                              unsigned long long seed);

txdnnStatus_t txdnnGetDropoutDescriptor(txdnnDropoutDescriptor_t dropoutDesc,
                          txdnnHandle_t handle,
                          float *dropout,
                          void **states,
                          unsigned long long *seed);

txdnnStatus_t txdnnDropoutForward(txdnnHandle_t handle,
                    const txdnnDropoutDescriptor_t dropoutDesc,
                    const txdnnTensorDescriptor_t xdesc,
                    const void *x,
                    const txdnnTensorDescriptor_t ydesc,
                    void *y,
                    void *reserveSpace,
                    size_t reserveSpaceSizeInBytes);


typedef enum {
  TXDNN_POINTWISE_ADD = 0,
  TXDNN_POINTWISE_ADD_SQUARE = 5,
  TXDNN_POINTWISE_DIV = 6,
  TXDNN_POINTWISE_MAX = 3,
  TXDNN_POINTWISE_MIN = 2,
  TXDNN_POINTWISE_MOD = 7,
  TXDNN_POINTWISE_MUL = 1,
  TXDNN_POINTWISE_POW = 8,
  TXDNN_POINTWISE_SUB = 9,

  TXDNN_POINTWISE_ABS = 10,
  TXDNN_POINTWISE_CEIL = 11,
  TXDNN_POINTWISE_COS = 12,
  TXDNN_POINTWISE_EXP = 13,
  TXDNN_POINTWISE_FLOOR = 14,
  TXDNN_POINTWISE_LOG = 15,
  TXDNN_POINTWISE_NEG = 16,
  TXDNN_POINTWISE_RSQRT = 17,
  TXDNN_POINTWISE_SIN = 18,
  TXDNN_POINTWISE_SQRT = 4,
  TXDNN_POINTWISE_TAN = 19,
  TXDNN_POINTWISE_ERF = 20,
  TXDNN_POINTWISE_IDENTITY = 21,
  TXDNN_POINTWISE_RECIPROCAL = 22,
  TXDNN_POINTWISE_ATAN2 = 23,

  TXDNN_POINTWISE_RELU_FWD = 100,
  TXDNN_POINTWISE_TANH_FWD = 101,
  TXDNN_POINTWISE_SIGMOID_FWD = 102,
  TXDNN_POINTWISE_ELU_FWD = 103,
  TXDNN_POINTWISE_GELU_FWD = 104,
  TXDNN_POINTWISE_SOFTPLUS_FWD = 105,
  TXDNN_POINTWISE_SWISH_FWD = 106,
  TXDNN_POINTWISE_GELU_APPROX_TANH_FWD = 107,

  TXDNN_POINTWISE_RELU_BWD = 200,
  TXDNN_POINTWISE_TANH_BWD = 201,
  TXDNN_POINTWISE_SIGMOID_BWD = 202,
  TXDNN_POINTWISE_ELU_BWD = 203,
  TXDNN_POINTWISE_GELU_BWD = 204,
  TXDNN_POINTWISE_SOFTPLUS_BWD = 205,
  TXDNN_POINTWISE_SWISH_BWD = 206,
  TXDNN_POINTWISE_GELU_APPROX_TANH_BWD = 207,

  TXDNN_POINTWISE_CMP_EQ = 300,
  TXDNN_POINTWISE_CMP_NEQ = 301,
  TXDNN_POINTWISE_CMP_GT = 302,
  TXDNN_POINTWISE_CMP_GE = 303,
  TXDNN_POINTWISE_CMP_LT = 304,
  TXDNN_POINTWISE_CMP_LE = 305,

  TXDNN_POINTWISE_LOGICAL_AND = 400,
  TXDNN_POINTWISE_LOGICAL_OR = 401,
  TXDNN_POINTWISE_LOGICAL_NOT = 402,

  TXDNN_POINTWISE_GEN_INDEX = 501,

  TXDNN_POINTWISE_BINARY_SELECT = 601,
} txdnnPointwiseMode_t;

typedef enum {
  TXDNN_LAYER_NORM = 0,
  TXDNN_INSTANCE_NORM = 1,
  TXDNN_BATCH_NORM = 2,
  TXDNN_GROUP_NORM = 3,
  TXDNN_RMS_NORM = 4,
} txdnnNormMode_t;

typedef enum {
  TXDNN_NORM_FWD_INFERENCE = 0,
  TXDNN_NORM_FWD_TRAINING = 1,
} txdnnNormFwdPhase_t;



/*
 *  Layer Normalization algorithm
 */
/** @addtogroup layernorm
 *
 *  @{
 */
/*! @brief Execute a layernorm forward layer
 *
 * @param handle         TXDNN handle (input)
 * @param mode           LayerNorm mode (input)
 * @param xDesc          Tensor descriptor for data input tensor x (input)
 * @param x              Data tensor x (input)
 * @param weightDesc     Tensor descriptor for data input tensor weight (input)
 * @param weight         Data tensor weight (input)
 * @param biasDesc       Tensor descriptor for data input tensor bias (input)
 * @param bias           Data tensor bias (input)
 * @param epsilon        Value to stablize inverse variance calculation (input)
 * @param normalized_dim Nomalized dimensions in the input array (input)
 * @param yDesc          Tensor descriptor for output data tensor y (input)
 * @param y              Data tensor y (output)
 * @param meanDesc       Tensor descriptor for output data tensor mean (input)
 * @param mean           Data tensor mean (output)
 * @param rstdDesc       Tensor descriptor for output data tensor rstd (input)
 * @param rstd           Data tensor rstd (output)
 * @return               txdnnStatus_t
 */
txdnnStatus_t TXDNNAPI txdnnLayerNormForward(txdnnHandle_t handle,
  txdnnNormMode_t mode,
  const txdnnTensorDescriptor_t xDesc,
  const void* x,
  const txdnnTensorDescriptor_t weightDesc,
  const void* weight,
  const txdnnTensorDescriptor_t biasDesc,
  const void* bias,
  const float epsilon,
  const int32_t normalized_dim,
  const txdnnTensorDescriptor_t yDesc,
  void* y,
  const txdnnTensorDescriptor_t meanDesc,
  void* mean,
  const txdnnTensorDescriptor_t rstdDesc,
  void* rstd);

/** @} */
// CLOSEOUT LAYERNORM DOXYGEN GROUP


/*
*  RoPE algorithm
*/

/* Function to perform forward RoPE */
txdnnStatus_t TXDNNAPI
txdnnRopeForward(txdnnHandle_t handle,
                 const txdnnTensorDescriptor_t xDesc,
                 const void* x,
                 const txdnnTensorDescriptor_t cosDesc,
                 const void* cos,
                 const txdnnTensorDescriptor_t sinDesc,
                 const void* sin,
                 const txdnnTensorDescriptor_t yDesc,
                 void* y);


/*
*  softmax algorithm
*/
typedef enum {
TXDNN_SOFTMAX_FAST     = 0, /* straightforward implementation */
TXDNN_SOFTMAX_ACCURATE = 1, /* subtract max from every point to avoid overflow */
TXDNN_SOFTMAX_LOG      = 2
} txdnnSoftmaxAlgorithm_t;

typedef enum {
TXDNN_SOFTMAX_MODE_INSTANCE = 0, /* compute the softmax over all C, H, W for each N */
TXDNN_SOFTMAX_MODE_CHANNEL  = 1  /* compute the softmax over all C for each H, W, N */
} txdnnSoftmaxMode_t;

/* Softmax functions: All of the form "output = alpha * Op(inputs) + beta * output" */

/* Function to perform forward softmax */
txdnnStatus_t TXDNNAPI
txdnnSoftmaxForward(txdnnHandle_t handle,
                    txdnnSoftmaxAlgorithm_t algo,
                    txdnnSoftmaxMode_t mode,
                    const void *alpha,
                    const txdnnTensorDescriptor_t xDesc,
                    const void *x,
                    const void *beta,
                    const txdnnTensorDescriptor_t yDesc,
                    void *y);


typedef enum {
  TXDNN_ATTR_POINTWISE_MODE = 0,
  TXDNN_ATTR_POINTWISE_MATH_PREC = 1,
  // TXDNN_ATTR_POINTWISE_NAN_PROPAGATION TXDNN_DEPRECATED_ENUM = 2,
  TXDNN_ATTR_POINTWISE_RELU_LOWER_CLIP = 3,
  TXDNN_ATTR_POINTWISE_RELU_UPPER_CLIP = 4,
  TXDNN_ATTR_POINTWISE_RELU_LOWER_CLIP_SLOPE = 5,
  TXDNN_ATTR_POINTWISE_ELU_ALPHA = 6,
  TXDNN_ATTR_POINTWISE_SOFTPLUS_BETA = 7,
  TXDNN_ATTR_POINTWISE_SWISH_BETA = 8,
  TXDNN_ATTR_POINTWISE_AXIS = 9,

  TXDNN_ATTR_CONVOLUTION_COMP_TYPE = 100,
  TXDNN_ATTR_CONVOLUTION_CONV_MODE = 101,
  TXDNN_ATTR_CONVOLUTION_DILATIONS = 102,
  TXDNN_ATTR_CONVOLUTION_FILTER_STRIDES = 103,
  TXDNN_ATTR_CONVOLUTION_POST_PADDINGS = 104,
  TXDNN_ATTR_CONVOLUTION_PRE_PADDINGS = 105,
  TXDNN_ATTR_CONVOLUTION_SPATIAL_DIMS = 106,

  TXDNN_ATTR_ENGINEHEUR_MODE = 200,
  TXDNN_ATTR_ENGINEHEUR_OPERATION_GRAPH = 201,
  TXDNN_ATTR_ENGINEHEUR_RESULTS = 202,
  TXDNN_ATTR_ENGINEHEUR_SM_COUNT_TARGET = 203,

  TXDNN_ATTR_ENGINECFG_ENGINE = 300,
  TXDNN_ATTR_ENGINECFG_INTERMEDIATE_INFO = 301,
  TXDNN_ATTR_ENGINECFG_KNOB_CHOICES = 302,
  TXDNN_ATTR_ENGINECFG_WORKSPACE_SIZE = 303,
  TXDNN_ATTR_ENGINECFG_SHARED_MEMORY_USED = 304,

  TXDNN_ATTR_EXECUTION_PLAN_HANDLE = 400,
  TXDNN_ATTR_EXECUTION_PLAN_ENGINE_CONFIG = 401,
  TXDNN_ATTR_EXECUTION_PLAN_WORKSPACE_SIZE = 402,
  TXDNN_ATTR_EXECUTION_PLAN_COMPUTED_INTERMEDIATE_UIDS = 403,
  TXDNN_ATTR_EXECUTION_PLAN_RUN_ONLY_INTERMEDIATE_UIDS = 404,
  TXDNN_ATTR_EXECUTION_PLAN_JSON_REPRESENTATION = 405,

  TXDNN_ATTR_INTERMEDIATE_INFO_UNIQUE_ID = 500,
  TXDNN_ATTR_INTERMEDIATE_INFO_SIZE = 501,
  TXDNN_ATTR_INTERMEDIATE_INFO_DEPENDENT_DATA_UIDS = 502,
  TXDNN_ATTR_INTERMEDIATE_INFO_DEPENDENT_ATTRIBUTES = 503,

  TXDNN_ATTR_KNOB_CHOICE_KNOB_TYPE = 600,
  TXDNN_ATTR_KNOB_CHOICE_KNOB_VALUE = 601,

  TXDNN_ATTR_OPERATION_CONVOLUTION_FORWARD_ALPHA = 700,
  TXDNN_ATTR_OPERATION_CONVOLUTION_FORWARD_BETA = 701,
  TXDNN_ATTR_OPERATION_CONVOLUTION_FORWARD_CONV_DESC = 702,
  TXDNN_ATTR_OPERATION_CONVOLUTION_FORWARD_W = 703,
  TXDNN_ATTR_OPERATION_CONVOLUTION_FORWARD_X = 704,
  TXDNN_ATTR_OPERATION_CONVOLUTION_FORWARD_Y = 705,
  TXDNN_ATTR_OPERATION_CONVOLUTION_BWD_DATA_ALPHA = 706,
  TXDNN_ATTR_OPERATION_CONVOLUTION_BWD_DATA_BETA = 707,
  TXDNN_ATTR_OPERATION_CONVOLUTION_BWD_DATA_CONV_DESC = 708,
  TXDNN_ATTR_OPERATION_CONVOLUTION_BWD_DATA_W = 709,
  TXDNN_ATTR_OPERATION_CONVOLUTION_BWD_DATA_DX = 710,
  TXDNN_ATTR_OPERATION_CONVOLUTION_BWD_DATA_DY = 711,
  TXDNN_ATTR_OPERATION_CONVOLUTION_BWD_FILTER_ALPHA = 712,
  TXDNN_ATTR_OPERATION_CONVOLUTION_BWD_FILTER_BETA = 713,
  TXDNN_ATTR_OPERATION_CONVOLUTION_BWD_FILTER_CONV_DESC = 714,
  TXDNN_ATTR_OPERATION_CONVOLUTION_BWD_FILTER_DW = 715,
  TXDNN_ATTR_OPERATION_CONVOLUTION_BWD_FILTER_X = 716,
  TXDNN_ATTR_OPERATION_CONVOLUTION_BWD_FILTER_DY = 717,

  TXDNN_ATTR_OPERATION_POINTWISE_PW_DESCRIPTOR = 750,
  TXDNN_ATTR_OPERATION_POINTWISE_XDESC = 751,
  TXDNN_ATTR_OPERATION_POINTWISE_BDESC = 752,
  TXDNN_ATTR_OPERATION_POINTWISE_YDESC = 753,
  TXDNN_ATTR_OPERATION_POINTWISE_ALPHA1 = 754,
  TXDNN_ATTR_OPERATION_POINTWISE_ALPHA2 = 755,
  TXDNN_ATTR_OPERATION_POINTWISE_DXDESC = 756,
  TXDNN_ATTR_OPERATION_POINTWISE_DYDESC = 757,
  TXDNN_ATTR_OPERATION_POINTWISE_TDESC = 758,

  TXDNN_ATTR_OPERATION_GENSTATS_MODE = 770,
  TXDNN_ATTR_OPERATION_GENSTATS_MATH_PREC = 771,
  TXDNN_ATTR_OPERATION_GENSTATS_XDESC = 772,
  TXDNN_ATTR_OPERATION_GENSTATS_SUMDESC = 773,
  TXDNN_ATTR_OPERATION_GENSTATS_SQSUMDESC = 774,

  TXDNN_ATTR_OPERATION_BN_FINALIZE_STATS_MODE = 780,
  TXDNN_ATTR_OPERATION_BN_FINALIZE_MATH_PREC = 781,
  TXDNN_ATTR_OPERATION_BN_FINALIZE_Y_SUM_DESC = 782,
  TXDNN_ATTR_OPERATION_BN_FINALIZE_Y_SQ_SUM_DESC = 783,
  TXDNN_ATTR_OPERATION_BN_FINALIZE_SCALE_DESC = 784,
  TXDNN_ATTR_OPERATION_BN_FINALIZE_BIAS_DESC = 785,
  TXDNN_ATTR_OPERATION_BN_FINALIZE_PREV_RUNNING_MEAN_DESC = 786,
  TXDNN_ATTR_OPERATION_BN_FINALIZE_PREV_RUNNING_VAR_DESC = 787,
  TXDNN_ATTR_OPERATION_BN_FINALIZE_UPDATED_RUNNING_MEAN_DESC = 788,
  TXDNN_ATTR_OPERATION_BN_FINALIZE_UPDATED_RUNNING_VAR_DESC = 789,
  TXDNN_ATTR_OPERATION_BN_FINALIZE_SAVED_MEAN_DESC = 790,
  TXDNN_ATTR_OPERATION_BN_FINALIZE_SAVED_INV_STD_DESC = 791,
  TXDNN_ATTR_OPERATION_BN_FINALIZE_EQ_SCALE_DESC = 792,
  TXDNN_ATTR_OPERATION_BN_FINALIZE_EQ_BIAS_DESC = 793,
  TXDNN_ATTR_OPERATION_BN_FINALIZE_ACCUM_COUNT_DESC = 794,
  TXDNN_ATTR_OPERATION_BN_FINALIZE_EPSILON_DESC = 795,
  TXDNN_ATTR_OPERATION_BN_FINALIZE_EXP_AVERATE_FACTOR_DESC = 796,

  TXDNN_ATTR_OPERATIONGRAPH_HANDLE = 800,
  TXDNN_ATTR_OPERATIONGRAPH_OPS = 801,
  TXDNN_ATTR_OPERATIONGRAPH_ENGINE_GLOBAL_COUNT = 802,

  TXDNN_ATTR_TENSOR_BYTE_ALIGNMENT = 900,
  TXDNN_ATTR_TENSOR_DATA_TYPE = 901,
  TXDNN_ATTR_TENSOR_DIMENSIONS = 902,
  TXDNN_ATTR_TENSOR_STRIDES = 903,
  TXDNN_ATTR_TENSOR_VECTOR_COUNT = 904,
  TXDNN_ATTR_TENSOR_VECTORIZED_DIMENSION = 905,
  TXDNN_ATTR_TENSOR_UNIQUE_ID = 906,
  TXDNN_ATTR_TENSOR_IS_VIRTUAL = 907,
  TXDNN_ATTR_TENSOR_IS_BY_VALUE = 908,
  TXDNN_ATTR_TENSOR_REORDERING_MODE = 909,
  TXDNN_ATTR_TENSOR_RAGGED_OFFSET_DESC = 913,

  TXDNN_ATTR_VARIANT_PACK_UNIQUE_IDS = 1000,
  TXDNN_ATTR_VARIANT_PACK_DATA_POINTERS = 1001,
  TXDNN_ATTR_VARIANT_PACK_INTERMEDIATES = 1002,
  TXDNN_ATTR_VARIANT_PACK_WORKSPACE = 1003,

  TXDNN_ATTR_LAYOUT_INFO_TENSOR_UID = 1100,
  TXDNN_ATTR_LAYOUT_INFO_TYPES = 1101,

  TXDNN_ATTR_KNOB_INFO_TYPE = 1200,
  TXDNN_ATTR_KNOB_INFO_MAXIMUM_VALUE = 1201,
  TXDNN_ATTR_KNOB_INFO_MINIMUM_VALUE = 1202,
  TXDNN_ATTR_KNOB_INFO_STRIDE = 1203,

  TXDNN_ATTR_ENGINE_OPERATION_GRAPH = 1300,
  TXDNN_ATTR_ENGINE_GLOBAL_INDEX = 1301,
  TXDNN_ATTR_ENGINE_KNOB_INFO = 1302,
  TXDNN_ATTR_ENGINE_NUMERICAL_NOTE = 1303,
  TXDNN_ATTR_ENGINE_LAYOUT_INFO = 1304,
  TXDNN_ATTR_ENGINE_BEHAVIOR_NOTE = 1305,
  TXDNN_ATTR_ENGINE_SM_COUNT_TARGET = 1306,

  TXDNN_ATTR_MATMUL_COMP_TYPE = 1500,
  TXDNN_ATTR_MATMUL_PADDING_VALUE = 1503,

  TXDNN_ATTR_OPERATION_MATMUL_ADESC = 1520,
  TXDNN_ATTR_OPERATION_MATMUL_BDESC = 1521,
  TXDNN_ATTR_OPERATION_MATMUL_CDESC = 1522,
  TXDNN_ATTR_OPERATION_MATMUL_DESC = 1523,
  // TXDNN_ATTR_OPERATION_MATMUL_IRREGULARLY_STRIDED_BATCH_COUNT TXDNN_DEPRECATED_ENUM = 1524,
  TXDNN_ATTR_OPERATION_MATMUL_GEMM_M_OVERRIDE_DESC = 1525,
  TXDNN_ATTR_OPERATION_MATMUL_GEMM_N_OVERRIDE_DESC = 1526,
  TXDNN_ATTR_OPERATION_MATMUL_GEMM_K_OVERRIDE_DESC = 1527,

  TXDNN_ATTR_REDUCTION_OPERATOR = 1600,
  TXDNN_ATTR_REDUCTION_COMP_TYPE = 1601,

  TXDNN_ATTR_OPERATION_REDUCTION_XDESC = 1610,
  TXDNN_ATTR_OPERATION_REDUCTION_YDESC = 1611,
  TXDNN_ATTR_OPERATION_REDUCTION_DESC = 1612,

  TXDNN_ATTR_OPERATION_BN_BWD_WEIGHTS_MATH_PREC = 1620,
  TXDNN_ATTR_OPERATION_BN_BWD_WEIGHTS_MEAN_DESC = 1621,
  TXDNN_ATTR_OPERATION_BN_BWD_WEIGHTS_INVSTD_DESC = 1622,
  TXDNN_ATTR_OPERATION_BN_BWD_WEIGHTS_BN_SCALE_DESC = 1623,
  TXDNN_ATTR_OPERATION_BN_BWD_WEIGHTS_X_DESC = 1624,
  TXDNN_ATTR_OPERATION_BN_BWD_WEIGHTS_DY_DESC = 1625,
  TXDNN_ATTR_OPERATION_BN_BWD_WEIGHTS_DBN_SCALE_DESC = 1626,
  TXDNN_ATTR_OPERATION_BN_BWD_WEIGHTS_DBN_BIAS_DESC = 1627,
  TXDNN_ATTR_OPERATION_BN_BWD_WEIGHTS_EQ_DY_SCALE_DESC = 1628,
  TXDNN_ATTR_OPERATION_BN_BWD_WEIGHTS_EQ_X_SCALE_DESC = 1629,
  TXDNN_ATTR_OPERATION_BN_BWD_WEIGHTS_EQ_BIAS = 1630,

  TXDNN_ATTR_RESAMPLE_MODE = 1700,
  TXDNN_ATTR_RESAMPLE_COMP_TYPE = 1701,
  TXDNN_ATTR_RESAMPLE_SPATIAL_DIMS = 1702,
  TXDNN_ATTR_RESAMPLE_POST_PADDINGS = 1703,
  TXDNN_ATTR_RESAMPLE_PRE_PADDINGS = 1704,
  TXDNN_ATTR_RESAMPLE_STRIDES = 1705,
  TXDNN_ATTR_RESAMPLE_WINDOW_DIMS = 1706,
  TXDNN_ATTR_RESAMPLE_NAN_PROPAGATION = 1707,
  TXDNN_ATTR_RESAMPLE_PADDING_MODE = 1708,

  TXDNN_ATTR_OPERATION_RESAMPLE_FWD_XDESC = 1710,
  TXDNN_ATTR_OPERATION_RESAMPLE_FWD_YDESC = 1711,
  TXDNN_ATTR_OPERATION_RESAMPLE_FWD_IDXDESC = 1712,
  // TXDNN_ATTR_OPERATION_RESAMPLE_FWD_ALPHA TXDNN_DEPRECATED_ENUM = 1713,
  // TXDNN_ATTR_OPERATION_RESAMPLE_FWD_BETA TXDNN_DEPRECATED_ENUM  = 1714,
  TXDNN_ATTR_OPERATION_RESAMPLE_FWD_DESC = 1716,

  TXDNN_ATTR_OPERATION_RESAMPLE_BWD_DXDESC = 1720,
  TXDNN_ATTR_OPERATION_RESAMPLE_BWD_DYDESC = 1721,
  TXDNN_ATTR_OPERATION_RESAMPLE_BWD_IDXDESC = 1722,
  // TXDNN_ATTR_OPERATION_RESAMPLE_BWD_ALPHA TXDNN_DEPRECATED_ENUM = 1723,
  // TXDNN_ATTR_OPERATION_RESAMPLE_BWD_BETA TXDNN_DEPRECATED_ENUM  = 1724,
  TXDNN_ATTR_OPERATION_RESAMPLE_BWD_DESC = 1725,
  TXDNN_ATTR_OPERATION_RESAMPLE_BWD_XDESC = 1726,
  TXDNN_ATTR_OPERATION_RESAMPLE_BWD_YDESC = 1727,

  TXDNN_ATTR_OPERATION_CONCAT_AXIS = 1800,
  TXDNN_ATTR_OPERATION_CONCAT_INPUT_DESCS = 1801,
  TXDNN_ATTR_OPERATION_CONCAT_INPLACE_INDEX = 1802,
  TXDNN_ATTR_OPERATION_CONCAT_OUTPUT_DESC = 1803,

  TXDNN_ATTR_OPERATION_SIGNAL_MODE = 1900,
  TXDNN_ATTR_OPERATION_SIGNAL_FLAGDESC = 1901,
  TXDNN_ATTR_OPERATION_SIGNAL_VALUE = 1902,
  TXDNN_ATTR_OPERATION_SIGNAL_XDESC = 1903,
  TXDNN_ATTR_OPERATION_SIGNAL_YDESC = 1904,

  TXDNN_ATTR_OPERATION_NORM_FWD_MODE = 2000,
  TXDNN_ATTR_OPERATION_NORM_FWD_PHASE = 2001,
  TXDNN_ATTR_OPERATION_NORM_FWD_XDESC = 2002,
  TXDNN_ATTR_OPERATION_NORM_FWD_MEAN_DESC = 2003,
  TXDNN_ATTR_OPERATION_NORM_FWD_INV_VARIANCE_DESC = 2004,
  TXDNN_ATTR_OPERATION_NORM_FWD_SCALE_DESC = 2005,
  TXDNN_ATTR_OPERATION_NORM_FWD_BIAS_DESC = 2006,
  TXDNN_ATTR_OPERATION_NORM_FWD_EPSILON_DESC = 2007,
  TXDNN_ATTR_OPERATION_NORM_FWD_EXP_AVG_FACTOR_DESC = 2008,
  TXDNN_ATTR_OPERATION_NORM_FWD_INPUT_RUNNING_MEAN_DESC = 2009,
  TXDNN_ATTR_OPERATION_NORM_FWD_INPUT_RUNNING_VAR_DESC = 2010,
  TXDNN_ATTR_OPERATION_NORM_FWD_OUTPUT_RUNNING_MEAN_DESC = 2011,
  TXDNN_ATTR_OPERATION_NORM_FWD_OUTPUT_RUNNING_VAR_DESC = 2012,
  TXDNN_ATTR_OPERATION_NORM_FWD_YDESC = 2013,
  TXDNN_ATTR_OPERATION_NORM_FWD_PEER_STAT_DESCS = 2014,

  TXDNN_ATTR_OPERATION_NORM_BWD_MODE = 2100,
  TXDNN_ATTR_OPERATION_NORM_BWD_XDESC = 2101,
  TXDNN_ATTR_OPERATION_NORM_BWD_MEAN_DESC = 2102,
  TXDNN_ATTR_OPERATION_NORM_BWD_INV_VARIANCE_DESC = 2103,
  TXDNN_ATTR_OPERATION_NORM_BWD_DYDESC = 2104,
  TXDNN_ATTR_OPERATION_NORM_BWD_SCALE_DESC = 2105,
  TXDNN_ATTR_OPERATION_NORM_BWD_EPSILON_DESC = 2106,
  TXDNN_ATTR_OPERATION_NORM_BWD_DSCALE_DESC = 2107,
  TXDNN_ATTR_OPERATION_NORM_BWD_DBIAS_DESC = 2108,
  TXDNN_ATTR_OPERATION_NORM_BWD_DXDESC = 2109,
  TXDNN_ATTR_OPERATION_NORM_BWD_PEER_STAT_DESCS = 2110,

  TXDNN_ATTR_OPERATION_RESHAPE_XDESC = 2200,
  TXDNN_ATTR_OPERATION_RESHAPE_YDESC = 2201,

  TXDNN_ATTR_RNG_DISTRIBUTION = 2300,
  TXDNN_ATTR_RNG_NORMAL_DIST_MEAN = 2301,
  TXDNN_ATTR_RNG_NORMAL_DIST_STANDARD_DEVIATION = 2302,
  TXDNN_ATTR_RNG_UNIFORM_DIST_MAXIMUM = 2303,
  TXDNN_ATTR_RNG_UNIFORM_DIST_MINIMUM = 2304,
  TXDNN_ATTR_RNG_BERNOULLI_DIST_PROBABILITY = 2305,

  TXDNN_ATTR_OPERATION_RNG_YDESC = 2310,
  TXDNN_ATTR_OPERATION_RNG_SEED = 2311,
  TXDNN_ATTR_OPERATION_RNG_DESC = 2312,
  TXDNN_ATTR_OPERATION_RNG_OFFSET_DESC = 2313,

  TXDNN_ATTR_INVALID = 2400,
} txdnnBackendAttributeName_t;

typedef enum {
  TXDNN_TYPE_HANDLE = 0,
  TXDNN_TYPE_DATA_TYPE,
  TXDNN_TYPE_BOOLEAN,
  TXDNN_TYPE_INT64,
  TXDNN_TYPE_FLOAT,
  TXDNN_TYPE_DOUBLE,
  TXDNN_TYPE_VOID_PTR,
  TXDNN_TYPE_CONVOLUTION_MODE,
  TXDNN_TYPE_HEUR_MODE,
  TXDNN_TYPE_KNOB_TYPE,
  // TXDNN_TYPE_NAN_PROPOGATION TXDNN_DEPRECATED_ENUM,
  TXDNN_TYPE_NUMERICAL_NOTE,
  TXDNN_TYPE_LAYOUT_TYPE,
  TXDNN_TYPE_ATTRIB_NAME,
  TXDNN_TYPE_POINTWISE_MODE,
  TXDNN_TYPE_BACKEND_DESCRIPTOR,
  TXDNN_TYPE_GENSTATS_MODE,
  TXDNN_TYPE_BN_FINALIZE_STATS_MODE,
  TXDNN_TYPE_REDUCTION_OPERATOR_TYPE,
  TXDNN_TYPE_BEHAVIOR_NOTE,
  TXDNN_TYPE_TENSOR_REORDERING_MODE,
  TXDNN_TYPE_RESAMPLE_MODE,
  TXDNN_TYPE_PADDING_MODE,
  TXDNN_TYPE_INT32,
  TXDNN_TYPE_CHAR,
  TXDNN_TYPE_SIGNAL_MODE,
  TXDNN_TYPE_FRACTION,
  TXDNN_TYPE_NORM_MODE,
  TXDNN_TYPE_NORM_FWD_PHASE,
  TXDNN_TYPE_RNG_DISTRIBUTION
} txdnnBackendAttributeType_t;

typedef enum {
  TXDNN_BACKEND_POINTWISE_DESCRIPTOR = 0,
  TXDNN_BACKEND_CONVOLUTION_DESCRIPTOR,
  TXDNN_BACKEND_ENGINE_DESCRIPTOR,
  TXDNN_BACKEND_ENGINECFG_DESCRIPTOR,
  TXDNN_BACKEND_ENGINEHEUR_DESCRIPTOR,
  TXDNN_BACKEND_EXECUTION_PLAN_DESCRIPTOR,
  TXDNN_BACKEND_INTERMEDIATE_INFO_DESCRIPTOR,
  TXDNN_BACKEND_KNOB_CHOICE_DESCRIPTOR,
  TXDNN_BACKEND_KNOB_INFO_DESCRIPTOR,
  TXDNN_BACKEND_LAYOUT_INFO_DESCRIPTOR,
  TXDNN_BACKEND_OPERATION_CONVOLUTION_FORWARD_DESCRIPTOR,
  TXDNN_BACKEND_OPERATION_CONVOLUTION_BACKWARD_FILTER_DESCRIPTOR,
  TXDNN_BACKEND_OPERATION_CONVOLUTION_BACKWARD_DATA_DESCRIPTOR,
  TXDNN_BACKEND_OPERATION_POINTWISE_DESCRIPTOR,
  TXDNN_BACKEND_OPERATION_GEN_STATS_DESCRIPTOR,
  TXDNN_BACKEND_OPERATIONGRAPH_DESCRIPTOR,
  TXDNN_BACKEND_VARIANT_PACK_DESCRIPTOR,
  TXDNN_BACKEND_TENSOR_DESCRIPTOR,
  TXDNN_BACKEND_MATMUL_DESCRIPTOR,
  TXDNN_BACKEND_OPERATION_MATMUL_DESCRIPTOR,
  TXDNN_BACKEND_OPERATION_BN_FINALIZE_STATISTICS_DESCRIPTOR,
  TXDNN_BACKEND_REDUCTION_DESCRIPTOR,
  TXDNN_BACKEND_OPERATION_REDUCTION_DESCRIPTOR,
  TXDNN_BACKEND_OPERATION_BN_BWD_WEIGHTS_DESCRIPTOR,
  TXDNN_BACKEND_RESAMPLE_DESCRIPTOR,
  TXDNN_BACKEND_OPERATION_RESAMPLE_FWD_DESCRIPTOR,
  TXDNN_BACKEND_OPERATION_RESAMPLE_BWD_DESCRIPTOR,
  TXDNN_BACKEND_OPERATION_CONCAT_DESCRIPTOR,
  TXDNN_BACKEND_OPERATION_SIGNAL_DESCRIPTOR,
  TXDNN_BACKEND_OPERATION_NORM_FORWARD_DESCRIPTOR,
  TXDNN_BACKEND_OPERATION_NORM_BACKWARD_DESCRIPTOR,
  TXDNN_BACKEND_OPERATION_RESHAPE_DESCRIPTOR,
  TXDNN_BACKEND_RNG_DESCRIPTOR,
  TXDNN_BACKEND_OPERATION_RNG_DESCRIPTOR,
} txdnnBackendDescriptorType_t;

typedef enum {
  TXDNN_BEHAVIOR_NOTE_RUNTIME_COMPILATION = 0,
  TXDNN_BEHAVIOR_NOTE_REQUIRES_FILTER_INT8x32_REORDER = 1,
  TXDNN_BEHAVIOR_NOTE_REQUIRES_BIAS_INT8x32_REORDER = 2,
  TXDNN_BEHAVIOR_NOTE_TYPE_COUNT,
} txdnnBackendBehaviorNote_t;

typedef enum {
  TXDNN_LAYOUT_TYPE_PREFERRED_NCHW = 0,
  TXDNN_LAYOUT_TYPE_PREFERRED_NHWC = 1,
  TXDNN_LAYOUT_TYPE_PREFERRED_PAD4CK = 2,
  TXDNN_LAYOUT_TYPE_PREFERRED_PAD8CK = 3,
  TXDNN_LAYOUT_TYPE_COUNT = 4,
} txdnnBackendLayoutType_t;

txdnnStatus_t TXDNNAPI txdnnBackendCreateDescriptor(txdnnBackendDescriptorType_t descriptorType,
                                                    txdnnBackendDescriptor_t* descriptor);

txdnnStatus_t TXDNNAPI txdnnBackendDestroyDescriptor(txdnnBackendDescriptor_t descriptor);

txdnnStatus_t TXDNNAPI txdnnBackendInitialize(txdnnBackendDescriptor_t descriptor);

txdnnStatus_t TXDNNAPI txdnnBackendFinalize(txdnnBackendDescriptor_t descriptor);

txdnnStatus_t TXDNNAPI txdnnBackendSetAttribute(txdnnBackendDescriptor_t descriptor,
                                                txdnnBackendAttributeName_t attributeName,
                                                txdnnBackendAttributeType_t attributeType, int64_t elementCount,
                                                const void* arrayOfElements);

txdnnStatus_t TXDNNAPI txdnnBackendGetAttribute(txdnnBackendDescriptor_t const descriptor,
                                                txdnnBackendAttributeName_t attributeName,
                                                txdnnBackendAttributeType_t attributeType,
                                                int64_t requestedElementCount, int64_t* elementCount,
                                                void* arrayOfElements);

txdnnStatus_t TXDNNAPI txdnnBackendExecute(txdnnHandle_t handle, txdnnBackendDescriptor_t executionPlan,
                                           txdnnBackendDescriptor_t variantPack);



#if defined(__cplusplus)
}
#endif